package excel

import (
	"bytes"
	"fmt"
	"os"
	"strings"
	"sync"
	"text/template"
)

type qlist struct {
	ls []string

	mutex sync.Mutex
}

var Qlist *qlist

func (q *qlist) Add(name string) {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	q.ls = append(q.ls, name)
}

func init() {
	Qlist = &qlist{}
}

// 字段
type FieldTypes struct {
	FName    string
	FType    string
	FComment string
}

// 通用解析结构
type CommonFields struct {
	Name               string       //结构体名称配置表名
	FieldNamesAndTypes []FieldTypes //所有结构字段类型
	PrimaryKey         string       //主键
	PrimaryKeyType     string       //主键类型
}

// GenTempGoFiles 生成配置go文件
func GenTempGoFiles(pack bool, data map[string][]string, name, config_dir string) {
	name = Case2Camel(name)
	var tmp []FieldTypes
	var prk, prkt string
	for k, v := range data {
		fty := parseType(v[1])
		fc := v[0]

		if strings.Contains(v[1], "index") {
			prk = k
			prkt = fty
		}
		ft := FieldTypes{
			FName:    k,
			FType:    fty,
			FComment: fc,
		}
		tmp = append(tmp, ft)
	}

	var tp *template.Template
	if pack {
		tp, _ = template.New("common").Parse(commonPackText)
	} else {
		tp, _ = template.New("common").Parse(commonText)
	}

	cf := &CommonFields{
		Name:               name,
		FieldNamesAndTypes: tmp,
		PrimaryKey:         prk,
		PrimaryKeyType:     prkt,
	}
	if cf.PrimaryKey == "" {
		return
	}

	var buf bytes.Buffer
	tp.Execute(&buf, cf)
	os.WriteFile(config_dir+name+".go", buf.Bytes(), 0644)
	Qlist.Add(name)
}

// 解析配置表类型
func parseType(data string) string {
	isKV := strings.Contains(data, "keyvalue")
	isList := strings.Contains(data, "list")
	isInt := strings.Contains(data, "int")
	isFloat := strings.Contains(data, "float")
	if isKV && isList && isInt {
		return "[]map[int]int"
	}
	if isKV && isList && isFloat {
		return "[]map[int]float32"
	}
	if isKV && isList {
		return "[]map[int]string"
	}
	if isKV && isInt {
		return "map[int]int"
	}
	if isKV && isFloat {
		return "map[int]float32"
	}
	if isKV {
		return "map[int]string"
	}

	if isList && isInt {
		return "[]int"
	}
	if isList && isFloat {
		return "[]float32"
	}

	if isList {
		return "[]string"
	}

	if isInt {
		return "int"
	}

	if isFloat {
		return "float32"
	}

	return "string"
}

// GenSpecialGoFiles 生成特殊配置go文件
func GenSpecialGoFiles(pack bool, data map[string][]string, name, config_dir string) {
	name = Case2Camel(name)
	var tmp []FieldTypes
	var prk, prkt string
	for k, v := range data {
		fty := parseType(v[1])
		fc := v[0]

		if strings.Contains(v[1], "index") {
			prk = k
			prkt = fty
		}
		ft := FieldTypes{
			FName:    k,
			FType:    fty,
			FComment: fc,
		}
		tmp = append(tmp, ft)
	}

	var tp *template.Template
	if pack {
		tp, _ = template.New("special").Parse(specialPackText)

	} else {
		tp, _ = template.New("special").Parse(specialText)
	}

	cf := &CommonFields{
		Name:               name,
		FieldNamesAndTypes: tmp,
		PrimaryKey:         prk,
		PrimaryKeyType:     prkt,
	}

	var buf bytes.Buffer
	tp.Execute(&buf, cf)
	os.WriteFile(config_dir+name+".go", buf.Bytes(), 0644)
	Qlist.Add(name)
}

// WriteAutoLoadGoFile 写自动重载配置函数
func WriteAutoLoadGoFile(config_dir string) {

	tp, err := template.New("special").Parse(reloadcfgText)
	if err != nil {
		fmt.Println("WriteAutoLoadGoFile err :", err)
		return
	}

	var buf bytes.Buffer
	tp.Execute(&buf, Qlist.ls)
	os.WriteFile(config_dir+"reloadcfg.go", buf.Bytes(), 0644)
}
